#ifndef S_STRING_HPP
#define S_STRING_HPP

#include "MasterString.hpp"
#include <cstring>

#define MAXSIZE 255

typedef struct {
    char ch[MAXSIZE + 1];
    int length;
} SString;

class SStringC : public MasterString<SString> {
protected:
    
public:
    Status strAssign(SString& t, const char* chars) override
    {
        if (!chars)
            return Status::Err;
        int len = strlen(chars);
        if (len == 0) {
            t.ch[0] = '\0';
            t.length = 0;
            return Status::Ok;
        }

        if (len > StringMaxSize)
            return Status::Err;

        strcpy(t.ch, chars);
        t.length = len;
        return Status::Ok;
    }

    Status strCopy(SString& t, SString s) override
    {
        return strAssign(t, s.ch);
    }

    inline bool strEmpty(const SString s) override
    {
        return s.length == 0;
    }

    CompareE strCompare(const SString s, const SString t) override
    {
        int result = strcmp(s.ch, t.ch);
        if (result < 0)
            return CompareE::Less;
        else if (result > 0)
            return CompareE::More;
        else
            return CompareE::Equal;
    }

    inline int strLength(const SString s) override
    {
        return s.length;
    }

    Status clearString(SString& s) override
    {
        s.ch[0] = '\0';
        s.length = 0;
        return Status::Ok;
    }

    Status concat(SString& s, const SString s1, const SString s2) override
    {
        int len1 = s1.length;
        int len2 = s2.length;

        if (len1 + len2 + 1 > StringMaxSize)
            return Status::Err;

        if (len1 + len2 == 0) {
            s.ch[0] = '\0';
            s.length = 0;
            return Status::Ok;
        }

        if (len1 > 0)
            strcpy(s.ch, s1.ch);
        if (len2 > 0)
            strcpy(s.ch + len1, s2.ch);
        s.length = len1 + len2;
        return Status::Ok;
    }

    Status subString(SString& sub, const SString s, int pos, int len) override
    {
        if (pos < 1 || pos > s.length || len < 0 || len > s.length - pos + 1)
            return Status::Err;

        if (len == 0) {
            sub.ch[0] = '\0';
            sub.length = 0;
            return Status::Ok;
        }

        strncpy(sub.ch, s.ch + pos - 1, len);
        sub.ch[len] = '\0';
        sub.length = len;
        return Status::Ok;
    }

    int index(const SString s, const SString t, int pos) override
    {
        int i = pos, j = 1;
        while (i <= s.length && j <= t.length) {
            if (s.ch[i] == t.ch[j]) {
                ++i;
                ++j;
            } else {
                i = i - j + 2;
                j = 1;
            }
        }
        if (j > t.length)
            return i - t.length;
        else
            return 0;
    }

    int index_kmp(const SString s, const SString t, int pos)
    {
        int i = pos, j = 1;
        while (i <= s.length && j <= t.length) {
            if (j == 0 || s.ch[i] == t.ch[j]) {
                ++i;
                ++j;
            } else {
            }
        }
        return 0;
    }

    Status replace(SString& s, SString t, SString v) override
    {
        return Status::Ok;
    }

    Status strInsert(SString& s, int pos, SString t) override
    {

        return Status::Ok;
    }

    Status strDelete(SString& s, int pos, int len) override
    {
        return Status::Ok;
    }

    Status destoryString(SString& s) override
    {
        return Status::Ok;
    }
};

#endif
